﻿using System;
using System.Diagnostics;
using System.Drawing;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Ruminate.GUI.Framework;
using Ruminate.Utils;
using Color = Microsoft.Xna.Framework.Color;
using Point = Microsoft.Xna.Framework.Point;
using Rectangle = Microsoft.Xna.Framework.Rectangle;

namespace Ruminate.GUI.Content {

    public class ScrollBars : Element {

        /*####################################################################*/
        /*                               Variables                            */
        /*####################################################################*/

        private BorderRenderer _renderer;
        private Texture2D _panel;
        private SlidingDoorRenderer _barRenderer, _holderRenderer;
        private ScrollBar _vertical, _horizontal;
        private const float MovementSpeed = .1f;

        private struct ScrollBar {
            public Texture2D 
                Bar, 
                Holder;
            public Rectangle
                IncreaseArea,
                DecreaseArea, 
                BarArea;
            public float 
                CurrentOffset,  //Current amount the bar has been moved
                MaxOffset,      //Maximum amount the bar can be moved
                Movement,       //Amount bar has been moved since being pressed
                Location,       //Location when bar was pressed
                Ratio; 
            public int MaxPanelOffset;
        }

        private Direction BarDirection { get; set; }

        /*####################################################################*/
        /*                        Node Initialization                         */
        /*####################################################################*/

        public ScrollBars(int x, int y, int width, int height) 
            : base(new Offset(x, y, width, height)) {

            BarDirection = Direction.None;
        }

        /*####################################################################*/
        /*                                 Events                             */
        /*####################################################################*/

        protected internal override void EnterPressed(MouseEventArgs e) {

            Reset();

            var location = e.Location;

            switch (BarDirection) {
                case Direction.Horizontal:

                    if (_horizontal.DecreaseArea.Contains(location)) {
                        _horizontal.Movement = -MovementSpeed;
                    } else if (_horizontal.IncreaseArea.Contains(location)) {
                        _horizontal.Movement = MovementSpeed;
                    } else if (_horizontal.BarArea.Contains(location)) {
                        _horizontal.Location = e.Location.X;
                    }
                    break;

                case Direction.Vertical:

                    if (_vertical.DecreaseArea.Contains(location)) {
                        _vertical.Movement = MovementSpeed;
                    } else if (_vertical.IncreaseArea.Contains(location)) {
                        _vertical.Movement = -MovementSpeed;
                    } else if (_vertical.BarArea.Contains(location)) {
                        _vertical.Location = e.Location.Y;
                    }
                    break;

                case Direction.Both:

                    if (_horizontal.DecreaseArea.Contains(location)) {
                        _horizontal.Movement = -MovementSpeed;
                    } else if (_horizontal.IncreaseArea.Contains(location)) {
                        _horizontal.Movement = MovementSpeed;
                    } else if (_horizontal.BarArea.Contains(location)) {
                        _horizontal.Location = e.Location.X;
                    } else if (_vertical.DecreaseArea.Contains(location)) {
                        _vertical.Movement = MovementSpeed;
                    } else if (_vertical.IncreaseArea.Contains(location)) {
                        _vertical.Movement = -MovementSpeed;
                    } else if (_vertical.BarArea.Contains(location)) {
                        _vertical.Location = e.Location.Y;
                    }
                    break;
            }
        }

        protected internal override void MouseMove(MouseEventArgs e) {

            var location = e.Location;

            if (!float.IsNaN(_horizontal.Location)) {

                _horizontal.CurrentOffset += location.X - _horizontal.Location;

                if (_horizontal.CurrentOffset > _horizontal.MaxOffset) {
                    _horizontal.CurrentOffset = _horizontal.MaxOffset;
                } else if (_horizontal.CurrentOffset < 0) {
                    _horizontal.CurrentOffset = 0;
                }

                _horizontal.BarArea.X = (int)(_horizontal.DecreaseArea.Right + _horizontal.CurrentOffset);
                _horizontal.Location = location.X;

            } else if (!float.IsNaN(_vertical.Location)) {

                _vertical.CurrentOffset += location.Y - _vertical.Location;

                if (_vertical.CurrentOffset > _vertical.MaxOffset) {
                    _vertical.CurrentOffset = _vertical.MaxOffset;
                } else if (_vertical.CurrentOffset < 0) {
                    _vertical.CurrentOffset = 0;
                }

                _vertical.BarArea.Y = (int)(_vertical.IncreaseArea.Bottom + _vertical.CurrentOffset);
                _vertical.Location = location.Y;

            }
        }

        protected internal override void MouseUp(MouseEventArgs e) {

            Reset();
        }

        protected internal override void ExitPressed(MouseEventArgs e) {

            Reset();
        }

        private void Reset() {

            _horizontal.Movement = float.NaN;
            _horizontal.Location = float.NaN;

            _vertical.Movement = float.NaN;
            _vertical.Location = float.NaN;
        }

        /*####################################################################*/
        /*                       Widget Initialization                        */
        /*####################################################################*/

        protected internal override void Init() {

            _renderer = (BorderRenderer)InstanceData.DefaultRenderers["Panel"];

            _barRenderer = (SlidingDoorRenderer)InstanceData.DefaultRenderers["ScrollBar"];
            _holderRenderer = (SlidingDoorRenderer)InstanceData.DefaultRenderers["ScrollBarHolder"];

            //Pixel size of panel to contain child elements
            var outerArea = BuildContainerSize();
            var outerFinalSize = new Point(
                (outerArea.X * 2) + outerArea.Width,
                (outerArea.Y * 2) + outerArea.Height);

            //figure out what scroll bars we are going to need
            if (outerFinalSize.X > LocationComponent.Size.X
                && outerFinalSize.Y > LocationComponent.Size.Y) {
                BarDirection = Direction.Both;
            } else if (outerFinalSize.X > LocationComponent.Size.X) {
                BarDirection = Direction.Horizontal;
            } else if (outerFinalSize.Y > LocationComponent.Size.Y) {
                BarDirection = Direction.Vertical;
            } else {
                return;
            }

            //Because we need to change the safe area we needed to realign this 
            //elements LocationComponent to the parents. 
            var safeArea = ChildRenderArea();

            int hBar;

            //Calculate the ratio
            switch (BarDirection) {
                case Direction.Horizontal:

                    _horizontal = new ScrollBar {
                        Ratio = ((float)outerFinalSize.X - safeArea.Width) / outerFinalSize.X,
                        DecreaseArea = new Rectangle(
                            LocationComponent.RenderBounds.Left
                            + _renderer.BorderWidth,
                            LocationComponent.RenderBounds.Bottom
                            - _renderer.BorderWidth
                            - _holderRenderer.EndWidth,
                            _holderRenderer.EndWidth,
                            _holderRenderer.EndWidth),
                        IncreaseArea = new Rectangle(
                            LocationComponent.RenderBounds.Right
                            - _renderer.BorderWidth
                            - _holderRenderer.EndWidth,
                            LocationComponent.RenderBounds.Bottom
                            - _renderer.BorderWidth
                            - _holderRenderer.EndWidth,
                            _holderRenderer.EndWidth,
                            _holderRenderer.EndWidth),
                        MaxPanelOffset = outerFinalSize.X - safeArea.Width,
                        Location = int.MinValue,
                        Movement = float.NaN
                    };
                    hBar = (int)((LocationComponent.Size.X - (_holderRenderer.EndWidth * 2)) * (1 - _horizontal.Ratio));
                    _horizontal.BarArea = new Rectangle(
                        LocationComponent.RenderBounds.Left
                        + _renderer.BorderWidth
                        + _holderRenderer.EndWidth,
                        LocationComponent.RenderBounds.Bottom
                        - _renderer.BorderWidth
                        - _holderRenderer.EndWidth + 1,
                        hBar,
                        _holderRenderer.Height
                    );
                    break;

                case Direction.Vertical:

                    _vertical = new ScrollBar {
                        Ratio = ((float)outerFinalSize.Y - safeArea.Height) / outerFinalSize.Y,
                        DecreaseArea = new Rectangle(
                            LocationComponent.RenderBounds.Right 
                                - _renderer.BorderWidth 
                                - _holderRenderer.Height,
                            LocationComponent.RenderBounds.Bottom 
                                - _renderer.BorderWidth 
                                - _holderRenderer.EndWidth,
                            _holderRenderer.Height,
                            _holderRenderer.Height),
                        IncreaseArea = new Rectangle(
                            LocationComponent.RenderBounds.Right 
                                - _renderer.BorderWidth 
                                - _holderRenderer.Height,
                            LocationComponent.RenderBounds.Top
                                + _renderer.BorderWidth,
                            _holderRenderer.Height,
                            _holderRenderer.Height),
                        MaxPanelOffset = outerFinalSize.Y - safeArea.Height,
                        Location = int.MinValue,
                        Movement = float.NaN
                    };
                    _vertical.BarArea = new Rectangle(
                        LocationComponent.RenderBounds.Right 
                            - _renderer.BorderWidth 
                            - _holderRenderer.Height + 1,
                        LocationComponent.RenderBounds.Top 
                            + _holderRenderer.Height
                            + _renderer.BorderWidth, 
                        _barRenderer.Height,
                        (int)((LocationComponent.Size.Y - (_holderRenderer.Height * 2)) * (1 - _vertical.Ratio))
                    );
                    break;

                case Direction.Both:

                    _horizontal = new ScrollBar {
                        Ratio = ((float)outerFinalSize.X - safeArea.Width) / outerFinalSize.X,
                        DecreaseArea = new Rectangle(
                            LocationComponent.RenderBounds.Left
                            + _renderer.BorderWidth,
                            LocationComponent.RenderBounds.Bottom
                            - _renderer.BorderWidth
                            - _holderRenderer.EndWidth,
                            _holderRenderer.EndWidth,
                            _holderRenderer.EndWidth),
                        IncreaseArea = new Rectangle(
                            LocationComponent.RenderBounds.Right
                            - _renderer.BorderWidth
                            - _holderRenderer.EndWidth * 2,
                            LocationComponent.RenderBounds.Bottom
                            - _renderer.BorderWidth
                            - _holderRenderer.EndWidth,
                            _holderRenderer.EndWidth,
                            _holderRenderer.EndWidth),
                        MaxPanelOffset = outerFinalSize.X - safeArea.Width,
                        Location = int.MinValue,
                        Movement = float.NaN
                    };
                    hBar = (int)((LocationComponent.Size.X - (_holderRenderer.EndWidth * 2) - _holderRenderer.EndWidth) * (1 - _horizontal.Ratio));
                    _horizontal.BarArea = new Rectangle(
                        LocationComponent.RenderBounds.Left
                        + _renderer.BorderWidth
                        + _holderRenderer.EndWidth,
                        LocationComponent.RenderBounds.Bottom
                        - _renderer.BorderWidth
                        - _holderRenderer.EndWidth + 1,
                        hBar,
                        _barRenderer.Height
                    );

                    _vertical = new ScrollBar {
                        Ratio = ((float)outerFinalSize.Y - safeArea.Height) / outerFinalSize.Y,
                        DecreaseArea = new Rectangle(
                            LocationComponent.RenderBounds.Right 
                                - _renderer.BorderWidth 
                                - _holderRenderer.Height,
                            LocationComponent.RenderBounds.Bottom 
                                - _renderer.BorderWidth 
                                - _holderRenderer.EndWidth * 2,
                            _holderRenderer.Height,
                            _holderRenderer.Height),
                        IncreaseArea = new Rectangle(
                            LocationComponent.RenderBounds.Right 
                                - _renderer.BorderWidth 
                                - _holderRenderer.Height,
                            LocationComponent.RenderBounds.Top
                                + _renderer.BorderWidth,
                            _holderRenderer.Height,
                            _holderRenderer.Height),
                        MaxPanelOffset = outerFinalSize.Y - safeArea.Height,
                        Location = int.MinValue,
                        Movement = float.NaN
                    };
                    _vertical.BarArea = new Rectangle(
                        LocationComponent.RenderBounds.Right 
                            - _renderer.BorderWidth 
                            - _holderRenderer.Height + 1,
                        LocationComponent.RenderBounds.Top 
                            + _holderRenderer.Height
                            + _renderer.BorderWidth, 
                        _barRenderer.Height,
                        (int)((LocationComponent.Size.Y - (_holderRenderer.Height * 2) - _holderRenderer.EndWidth) * (1 - _vertical.Ratio))
                    );
                    break;
            }
        }

        protected internal override void Render() {

            var size = LocationComponent.Size.ToPoint();
            _panel = _renderer.Render(size);            

            int hBar, hHolder, vBar, vHolder;
            var x = LocationComponent.RenderBounds.Width;
            var y = LocationComponent.RenderBounds.Height;

            switch (BarDirection) {
                case Direction.Horizontal:

                    hHolder = x - 2 * _renderer.BorderWidth;
                    hBar = (int)((x - (_barRenderer.Height * 2)) * (1 - _horizontal.Ratio));
                    _horizontal.Holder = _holderRenderer.Render(new Point(hHolder, _holderRenderer.Height), 0);
                    _horizontal.Bar = _barRenderer.Render(new Point(hBar, _holderRenderer.Height), 0);
                    _horizontal.MaxOffset = hHolder - hBar - (_holderRenderer.EndWidth * 2);
                    break;

                case Direction.Vertical:

                    vHolder = y - 2 * _renderer.BorderWidth;
                    vBar = (int)((y - (_barRenderer.Height * 2)) * (1 - _vertical.Ratio));
                    _vertical.Holder = _holderRenderer.Render(new Point(vHolder, _holderRenderer.Height), 0)
                        .Transform(InstanceData.GraphicsDevice, RotateFlipType.Rotate90FlipX);
                    _vertical.Bar = _barRenderer.Render(new Point(vBar, _barRenderer.Height), 0)
                        .Transform(InstanceData.GraphicsDevice, RotateFlipType.Rotate90FlipX);
                    _vertical.MaxOffset = vHolder - vBar - (_holderRenderer.EndWidth * 2);
                    break;

                case Direction.Both:

                    hHolder = x - 2 * _renderer.BorderWidth - _holderRenderer.EndWidth;
                    hBar = (int)((x - (_barRenderer.Height * 2) - _holderRenderer.EndWidth) * (1 - _horizontal.Ratio));
                    _horizontal.Holder = _holderRenderer.Render(new Point(hHolder, _holderRenderer.Height), 0);
                    _horizontal.Bar = _barRenderer.Render(new Point(hBar, _holderRenderer.Height), 0);
                    _horizontal.MaxOffset = hHolder - hBar - (_holderRenderer.EndWidth * 2);

                    vHolder = y - 2 * _renderer.BorderWidth - _holderRenderer.EndWidth;
                    vBar = (int)((y - (_barRenderer.Height * 2) - _holderRenderer.EndWidth) * (1 - _vertical.Ratio));
                    _vertical.Holder = _holderRenderer.Render(new Point(vHolder, _holderRenderer.Height), 0)
                        .Transform(InstanceData.GraphicsDevice, RotateFlipType.Rotate90FlipX);
                    _vertical.Bar = _barRenderer.Render(new Point(vBar, _barRenderer.Height), 0)
                        .Transform(InstanceData.GraphicsDevice, RotateFlipType.Rotate90FlipX);
                    _vertical.MaxOffset = vHolder - vBar - (_holderRenderer.EndWidth * 2);
                    break;
            }
        }

        protected internal override Rectangle ChildRenderArea() {

            var temp = _renderer.BuildSafeArea(LocationComponent.Size.ToPoint());

            switch (FindBarDirection()) {
                case Direction.Horizontal:
                    temp.Height -= _holderRenderer.Height;
                    break;
                case Direction.Vertical:
                    temp.Width -= _holderRenderer.Height;
                    break;
                case Direction.Both:
                    temp.Height -= _holderRenderer.Height;
                    temp.Width -= _holderRenderer.Height;
                    break;
            }

            return temp;
        }

        /*####################################################################*/
        /*                                Logic                               */
        /*####################################################################*/

        protected internal override void Update() {

            var location = InputSystem.MouseLocation;

            switch (BarDirection) {
                case Direction.Horizontal:                    

                    if (float.IsNaN(_horizontal.Movement)) { return; }

                    if (!_horizontal.DecreaseArea.Contains(location)
                        && !_horizontal.IncreaseArea.Contains(location)
                        && !_horizontal.BarArea.Contains(location)) {

                        ExitPressed(null);
                    }

                    _horizontal.CurrentOffset += _horizontal.Movement;

                    if (_horizontal.CurrentOffset > _horizontal.MaxOffset) {
                        _horizontal.CurrentOffset = _horizontal.MaxOffset;
                        ExitPressed(null);
                    } else if (_horizontal.CurrentOffset < 0) {
                        _horizontal.CurrentOffset = 0;
                        ExitPressed(null);
                    }

                    _horizontal.BarArea.X = _horizontal.DecreaseArea.Right + (int)_horizontal.CurrentOffset;

                    break;

                case Direction.Vertical:                    

                    if (float.IsNaN(_vertical.Movement)) { return; }

                    if (!_vertical.DecreaseArea.Contains(location)
                        && !_vertical.IncreaseArea.Contains(location)
                        && !_vertical.BarArea.Contains(location)) {

                        ExitPressed(null);
                    }

                    _vertical.CurrentOffset += _vertical.Movement;

                    if (_vertical.CurrentOffset > _vertical.MaxOffset) {
                        _vertical.CurrentOffset = _vertical.MaxOffset;
                        ExitPressed(null);
                    } else if (_vertical.CurrentOffset < 0) {
                        _vertical.CurrentOffset = 0;
                        ExitPressed(null);
                    }

                    _vertical.BarArea.Y = _vertical.IncreaseArea.Bottom + (int)_vertical.CurrentOffset;

                    break;

                case Direction.Both:

                    if (!_horizontal.DecreaseArea.Contains(location)
                        && !_horizontal.IncreaseArea.Contains(location)
                        && !_horizontal.BarArea.Contains(location)
                        && !_vertical.DecreaseArea.Contains(location)
                        && !_vertical.IncreaseArea.Contains(location)
                        && !_vertical.BarArea.Contains(location)) {

                        ExitPressed(null);
                    }

                    if (!float.IsNaN(_horizontal.Movement)) {

                        _horizontal.CurrentOffset += _horizontal.Movement;

                        if (_horizontal.CurrentOffset > _horizontal.MaxOffset) {
                            _horizontal.CurrentOffset = _horizontal.MaxOffset;
                            ExitPressed(null);
                        } else if (_horizontal.CurrentOffset < 0) {
                            _horizontal.CurrentOffset = 0;
                            ExitPressed(null);
                        }

                        _horizontal.BarArea.X = _horizontal.DecreaseArea.Right + (int)_horizontal.CurrentOffset;
                    }

                    if (!float.IsNaN(_vertical.Movement)) {

                        _vertical.CurrentOffset += _vertical.Movement;

                        if (_vertical.CurrentOffset > _vertical.MaxOffset) {
                            _vertical.CurrentOffset = _vertical.MaxOffset;
                            ExitPressed(null);
                        } else if (_vertical.CurrentOffset < 0) {
                            _vertical.CurrentOffset = 0;
                            ExitPressed(null);
                        }

                        _vertical.BarArea.Y = _vertical.IncreaseArea.Bottom + (int)_vertical.CurrentOffset;
                    }

                    break;
            }
        }

        protected internal override void Draw() {

            SpriteBatch.Draw(_panel, LocationComponent.RenderBounds, Color.White);

            var x = (float)Math.Round((_horizontal.CurrentOffset / _horizontal.MaxOffset) * _horizontal.MaxPanelOffset);
            var y = (float)Math.Round((_vertical.CurrentOffset / _vertical.MaxOffset) * _vertical.MaxPanelOffset);

            if (float.IsNaN(x)) x = 0;
            if (float.IsNaN(y)) y = 0;

            LocationComponent.ChildOffset = new Vector2(x,y);

            var xOffset = _horizontal.CurrentOffset;
            var yOffset = _vertical.CurrentOffset;

            switch (BarDirection) {
                case Direction.Horizontal:

                    SpriteBatch.Draw(
                        _horizontal.Holder,
                        new Vector2(
                            LocationComponent.RenderLocation.X + _renderer.BorderWidth,
                            LocationComponent.RenderBounds.Bottom - _renderer.BorderWidth - _holderRenderer.Height),
                        Color.White);
                    SpriteBatch.Draw(
                        _horizontal.Bar,
                        new Vector2(
                            xOffset + LocationComponent.RenderLocation.X + _renderer.BorderWidth + _holderRenderer.EndWidth,
                            LocationComponent.RenderBounds.Bottom - _renderer.BorderWidth - _holderRenderer.Height),
                        Color.White);
                    break;

                case Direction.Vertical:

                    SpriteBatch.Draw(
                        _vertical.Holder,
                        new Vector2(
                            LocationComponent.RenderBounds.Right - _renderer.BorderWidth - _holderRenderer.Height, 
                            LocationComponent.RenderLocation.Y + _renderer.BorderWidth),
                        Color.White);
                    SpriteBatch.Draw(
                        _vertical.Bar,
                        new Vector2(
                            LocationComponent.RenderBounds.Right - _renderer.BorderWidth - _barRenderer.Height,
                            yOffset + LocationComponent.RenderLocation.Y + _renderer.BorderWidth + _holderRenderer.EndWidth),
                        Color.White);
                    break;

                case Direction.Both:

                    SpriteBatch.Draw(
                        _horizontal.Holder,
                        new Vector2(
                            LocationComponent.RenderLocation.X + _renderer.BorderWidth,
                            LocationComponent.RenderBounds.Bottom - _renderer.BorderWidth - _holderRenderer.Height),
                        Color.White);
                    SpriteBatch.Draw(
                        _horizontal.Bar,
                        new Vector2(
                            xOffset + LocationComponent.RenderLocation.X + _renderer.BorderWidth + _holderRenderer.EndWidth,
                            LocationComponent.RenderBounds.Bottom - _renderer.BorderWidth - _holderRenderer.Height),
                        Color.White);

                    SpriteBatch.Draw(
                        _vertical.Holder,
                        new Vector2(
                            LocationComponent.RenderBounds.Right - _renderer.BorderWidth - _holderRenderer.Height, 
                            LocationComponent.RenderLocation.Y + _renderer.BorderWidth),
                        Color.White);
                    SpriteBatch.Draw(
                        _vertical.Bar,
                        new Vector2(
                            LocationComponent.RenderBounds.Right - _renderer.BorderWidth - _barRenderer.Height,
                            yOffset + LocationComponent.RenderLocation.Y + _renderer.BorderWidth + _holderRenderer.EndWidth),
                        Color.White);
                    break;
            }

            DrawDebug();
        }

        /*####################################################################*/
        /*                               Helpers                              */
        /*####################################################################*/

        private Direction FindBarDirection() {

            //Pixel size of panel to contain child elements
            var outerArea = BuildContainerSize();
            var outerFinalSize = new Point(
                (outerArea.X * 2) + outerArea.Width,
                (outerArea.Y * 2) + outerArea.Height);

            //figure out what scroll bars we are going to need
            if (outerFinalSize.X > LocationComponent.Size.X && outerFinalSize.Y > LocationComponent.Size.Y) {
                return Direction.Both;
            } else if (outerFinalSize.X > LocationComponent.Size.X) {
                return Direction.Horizontal;
            } else if (outerFinalSize.Y > LocationComponent.Size.Y) {
                return Direction.Vertical;
            } 
            
            return Direction.None;
        }

        private Rectangle BuildContainerSize() {

            if (Children.Count == 0) {
                return Rectangle.Empty;
            }

            var left = int.MaxValue;
            var right = int.MinValue;

            var top = int.MaxValue;
            var bottom = int.MinValue;

            foreach (var child in Children) {

                left = (left > (int)child.LocationComponent.Location.X)
                    ? (int)child.LocationComponent.Location.X
                    : left;

                right = (right < (int)child.LocationComponent.Location.X
                    + (int)child.LocationComponent.Size.X)
                    ? (int)child.LocationComponent.Location.X
                        + (int)child.LocationComponent.Size.X
                    : right;

                top = (top > (int)child.LocationComponent.Location.Y)
                    ? (int)child.LocationComponent.Location.Y
                    : top;

                bottom = (bottom < (int)child.LocationComponent.Location.Y
                    + (int)child.LocationComponent.Size.Y)
                    ? (int)child.LocationComponent.Location.Y
                        + (int)child.LocationComponent.Size.Y
                    : bottom;
            }

            return new Rectangle(left, top, right - left, bottom - top);
        }

        [Conditional("SCROLLBARS")]
        private void DrawDebug() {

            var outerArea = BuildContainerSize();
            var outerFinalSize = new Rectangle(
                LocationComponent.RenderSafeArea.X - (int)LocationComponent.ChildOffset.X,
                LocationComponent.RenderSafeArea.Y - (int)LocationComponent.ChildOffset.Y,
                (outerArea.X * 2) + outerArea.Width,
                (outerArea.Y * 2) + outerArea.Height);

            //Safe area
            SpriteBatch.Draw(DebugUtils.White, LocationComponent.RenderSafeArea, Color.DarkBlue);

            //Child container
            SpriteBatch.Draw(DebugUtils.White, outerFinalSize, Color.DarkRed);

            //This should overlap outerFinalSize if the Ratio is correct
            SpriteBatch.Draw(DebugUtils.White, 
                new Rectangle(
                    LocationComponent.RenderSafeArea.X,
                    LocationComponent.RenderSafeArea.Y,
                    (int)(LocationComponent.RenderSafeArea.Width * (1 / (1 - _horizontal.Ratio))),
                    (int)(LocationComponent.RenderSafeArea.Height * (1 / (1 - _vertical.Ratio)))), 
                Color.LightSalmon);

            //Location of buttons for scroll bars
            switch (BarDirection) {
                case Direction.Horizontal:
                    SpriteBatch.Draw(DebugUtils.White, _horizontal.DecreaseArea,  Color.DarkGreen);
                    SpriteBatch.Draw(DebugUtils.White, _horizontal.IncreaseArea,  Color.Green);
                    SpriteBatch.Draw(DebugUtils.White, _horizontal.BarArea, Color.Black);
                    break;
                case Direction.Vertical:
                    SpriteBatch.Draw(DebugUtils.White, _vertical.DecreaseArea,  Color.DarkGreen);
                    SpriteBatch.Draw(DebugUtils.White, _vertical.IncreaseArea, Color.Green);
                    SpriteBatch.Draw(DebugUtils.White, _vertical.BarArea, Color.Black);
                    break;
                case Direction.Both:
                    SpriteBatch.Draw(DebugUtils.White, _horizontal.DecreaseArea,  Color.DarkGreen);
                    SpriteBatch.Draw(DebugUtils.White, _horizontal.IncreaseArea,  Color.Green);
                    SpriteBatch.Draw(DebugUtils.White, _horizontal.BarArea, Color.Black);

                    SpriteBatch.Draw(DebugUtils.White, _vertical.DecreaseArea,  Color.DarkGreen);
                    SpriteBatch.Draw(DebugUtils.White, _vertical.IncreaseArea, Color.Green);
                    SpriteBatch.Draw(DebugUtils.White, _vertical.BarArea, Color.Black);
                    break;
            }             
        }
    }
}